package cn.lingyangwl.framework.tool.core.jar;

import cn.lingyangwl.framework.tool.core.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * 打包方式
 *
 * @author shenguangyang
 */
public abstract class JarBuildWay {
    protected CopyResourcesInfo copyResourcesInfo;
    /**
     * 目标目录路径
     *
     * @see TargetFile
     */
    protected String targetDirPath;

    /**
     * jar包名字
     */
    protected String jarName;

    /**
     * 拷贝时候需要排除的文件
     */
    protected final List<String> copyExcludeFiles = new ArrayList<>();

    /**
     * 返回true, 则完成拷贝, 否则不拷贝
     */
    protected Function<JarResourcesFile, Boolean> copyAfterCallback;

    public JarBuildWay(CopyResourcesInfo copyResourcesInfo) {
        this.copyResourcesInfo = copyResourcesInfo;

        String customDirPath = copyResourcesInfo.getCustomDirPath();
        String dirName = copyResourcesInfo.getDirName();
        if (StringUtils.isEmpty(customDirPath)) {
            this.targetDirPath = JarResourcesCopyConstant.LIB_CACHE_PATH + File.separator + dirName;
        } else {
            this.targetDirPath = customDirPath + File.separator + dirName;
        }
    }

    /**
     * 执行, 主逻辑
     */
    public void exec() throws IOException {
        doCopyResourcesToLocal();
    }

    /**
     * 完成将资源拷贝到本地
     */
    protected abstract void doCopyResourcesToLocal() throws IOException;

    protected static void writeFile(InputStream is, File file) throws Exception {
        if (file != null) {
            // 推荐使用字节流读取，因为虽然读取的是文件，如果是 .exe, .c 这种文件，用字符流读取会有乱码
            try (OutputStream os = new BufferedOutputStream(java.nio.file.Files.newOutputStream(file.toPath()))) {
                //这里用小数组读取，使用file.length()来一次性读取可能会出错（亲身试验）
                byte[] bytes = new byte[2048 * 1024];
                int len;
                while ((len = is.read(bytes)) != -1) {
                    os.write(bytes, 0, len);
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
